package com.hy.study.demo.complexquerydemo.builder;

import com.hy.study.demo.complexquerydemo.bean.view.QueryCombinationCondition;
import com.hy.study.demo.complexquerydemo.utils.FieldRemark;
import com.hy.study.demo.complexquerydemo.utils.Operator;
import com.hy.study.demo.complexquerydemo.utils.StringSymbol;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import java.lang.reflect.Field;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author huyong
 * @description 查询构造器
 * @date 2021/10/15
 **/
public abstract class QueryBuilder {
    /**
     * 构造成查询的条件
     *
     * @param combinationConditions
     * @return
     */
    protected String condition(Set<QueryCombinationCondition> combinationConditions, Class<?> target) {
        if (CollectionUtils.isEmpty(combinationConditions)) {
            return "";
        }
        //分组处理
        Map<Operator, List<QueryCombinationCondition>> groupMap = combinationConditions.stream().collect(Collectors.groupingBy(QueryCombinationCondition::getGroupOperator));
        StringBuffer buffer = new StringBuffer();
        String endOperator = "";
        for (Map.Entry<Operator, List<QueryCombinationCondition>> entry : groupMap.entrySet()) {
            String group = entry.getKey().getOpr();
            //拼接查询条件
            List<QueryCombinationCondition> value = entry.getValue();
            if (!CollectionUtils.isEmpty(value)) {
                buffer.append(StringSymbol.LEFT_BRACKET);
                QueryCombinationCondition condition1 = value.stream().findFirst().get();
                for (QueryCombinationCondition condition : value) {
                    Set<String> fields = condition.getField();
                    String opr = getOpr(condition.getOperator());
                    Iterator<String> iterator = fields.iterator();
                    while (iterator.hasNext()) {
                        String field = iterator.next();
                        String column = this.getColumnName(target, field);
                        if (StringUtils.isAnyBlank(field, column)) {
                            continue;
                        }
                        buffer.append(column).append(StringSymbol.CRLF).append(opr).append(StringSymbol.CRLF);
                        if (Operator.LIKE == condition.getOperator() || Operator.NOT_LIKE == condition.getOperator()) {
                            buffer.append("concat(concat('%',").
                                    append(StringSymbol.HASH).append(StringSymbol.LEFT_BRACE).append("bean.").append(field).append(StringSymbol.CRLF).append(StringSymbol.RIGHT_BRACE).append("),'%')");
                        } else {
                            buffer.append(StringSymbol.HASH).append(StringSymbol.LEFT_BRACE).append("bean.").append(field).append(StringSymbol.CRLF).append(StringSymbol.RIGHT_BRACE);
                        }
                        buffer.append(group).append(StringSymbol.CRLF);
                    }
                }
                buffer.delete(buffer.lastIndexOf(group), buffer.length());
                buffer.append(StringSymbol.RIGHT_BRACKET);
                String groupOpr = condition1.getGroupOperator().getOpr();
                endOperator = groupOpr;
                buffer.append(groupOpr);
            }
        }
        buffer.delete(buffer.lastIndexOf(endOperator), buffer.length());
        return buffer.toString();
    }

    /**
     * 每个字段的操作关系
     *
     * @param operator
     * @return
     */
    private String getOpr(Operator operator) {
        String opr = "";
        if (operator == null || StringUtils.isBlank(operator.getOpr())) {
            opr = Operator.AND.getOpr();
        } else {
            opr = operator.getOpr();
        }
        if (Operator.AND.getOpr().equalsIgnoreCase(opr) || Operator.OR.getOpr().equalsIgnoreCase(opr)) {
            opr = StringSymbol.EQUALS;
        }
        return opr;
    }

    /**
     * 获取字段值对应的数据库列表名称
     *
     * @param target
     * @param fieldName
     * @return
     */
    private String getColumnName(Class<?> target, String fieldName) {
        String column = "";
        try {
            Field field = target.getDeclaredField(fieldName);
            field.setAccessible(true);
            FieldRemark remark = field.getAnnotation(FieldRemark.class);
            if (remark != null && StringUtils.isNotBlank(remark.column())) {
                column = remark.column();
            }
        } catch (NoSuchFieldException e) {
            // ignore error
        }
        return column;
    }

}
